package cn.acrdpm.consumer;

import cn.acrdpm.constant.MsgLogStatus;
import cn.acrdpm.entity.Mail;
import cn.acrdpm.entity.MsgLog;
import cn.acrdpm.service.MsgLogService;
import cn.acrdpm.tools.EmailUtil;
import cn.acrdpm.tools.JsonUtils;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.mail.EmailException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 *  邮件消费者
 * @author 张敏
 * @date 2021/3/11
 */
@Slf4j
@Component
@PropertySource("classpath:rabbitmq.properties")
@RabbitListener(queues = "${mail_topic_queue}")
public class MailConsumer {

    @Autowired
    private MsgLogService msgLogService;


    @RabbitHandler
    public void consume(Message message,Mail mail, Channel channel) {

        log.info("消息 {}",message);
        //获得消息体转化消息实体类
        Mail mail1 = JsonUtils.parseToObject(new String(message.getBody()), Mail.class);
        log.info("message的消息体 {}" ,mail1);
        //验证可以直接接受mail 类型的消息
        log.info("mail {}",mail);

        String msgId = mail.getMsgId();
        MsgLog msgLog = msgLogService.selectByMsgId(msgId);
        if (null == msgLog || msgLog.getStatus().equals(MsgLogStatus.CONSUMED_SUCCESS)) {
            // 消费幂等性：确定不是重复的消息：及消费完成的消息
            log.info("重复消费, msgId: {}", msgId);
            return;
        }
         //获取投送标签
        long tag = message.getMessageProperties().getDeliveryTag();
        try {
            boolean success = EmailUtil.sendEmail(mail);
            if (success) {
                log.info("成功发送消息");
                msgLogService.updateStatus(msgId, MsgLogStatus.CONSUMED_SUCCESS);
                // 消费确认手动ack
                channel.basicAck(tag, false);
            } else {
                channel.basicNack(tag, false, true);
            }
        } catch (EmailException e) {
            log.error("email 发送异常" , e);
        } catch (IOException e) {
            log.error("消息处理异常" , e);
        }

    }
}
